﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SCRUM.Core.BusinessObjects;
using SCRUM.Core.DAO;
using System.Collections.Specialized;   // string dictionary
using SCRUM.Core.Exceptions.Database;


/// <summary>
/// Widget to define teams and assign them to projects
/// </summary>
public partial class TeamDefinition : WidgetBase
{

    /// <summary>
    /// Gets the name of the widget. It must be exactly the same as the folder that contains the widget.
    /// </summary>
    /// <value>PrototypeWidget</value>
    public override string Name
    {
        get { return "TeamDefinition"; }
    }

    /// <summary>
    /// Gets the title. Title is shown in the header of the widget container.
    /// </summary>
    /// <value>The title.</value>
    public override string Title
    {
        get { return (string)GetLocalResourceObject("Title"); }
    }


    /// <summary>
    /// This method works as a substitute for Page_Load. You should use this method for
    /// data binding etc. instead of Page_Load.
    /// </summary>
    public override void LoadWidget()
    {
        RefreshTeamControls();
    }

    #region [PROJECT-TEAM FILTER]

    /// <summary>
    /// /// Sets handlers for events.
    /// </summary>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void Page_Init(object sender, EventArgs e)
    {
        this.Team.SelectedProjectChangedEvent += new EventHandler(this.SelectedProjectChanged);
        this.Team.SelectedTeamChangedEvent += new EventHandler(this.SelectedTeamChanged);
    }

    /// <summary>
    /// User selected some project
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void SelectedProjectChanged(object sender, EventArgs e)
    {
        RefreshTeamControls();
        LoadUsersInRoles();
    }

    /// <summary>
    /// User selected some team
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void SelectedTeamChanged(object sender, EventArgs e)
    {
        RefreshTeamControls();
        LoadUsersInRoles();
    }

    /// <summary>
    /// Refreshes the team controls acording to team filter
    /// </summary>
    private void RefreshTeamControls()
    {
        this.ImageButtonDeleteTeam.Visible = this.Team.SelectedTeamID != -1;
        this.ImageButtonAddTeam.Visible = this.Team.SelectedProjectID != -1;
        this.ButtonAddNewTeamMember.Visible = this.Team.SelectedProjectID != -1;
    }

    #endregion

    #region [TEAM MANAGEMENT]
    /// <summary>
    /// User wants to add new team
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="ce">The <see cref="System.Web.UI.WebControls.CommandEventArgs"/> instance containing the event data.</param>
    public void AddNewTeam(object sender, CommandEventArgs ce)
    {
        ShowAddNewTeam(true);
    }

    /// <summary>
    /// Shows the 'add new team' area
    /// </summary>
    /// <param name="show">if set to <c>true</c> [show].</param>
    private void ShowAddNewTeam(bool show)
    {
        this.PanelNewTeam.Visible = show;
        this.ImageButtonAddTeam.Visible = !show;
    }

    /// <summary>
    /// Deletes the team selected in team filter.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="ce">The <see cref="System.Web.UI.WebControls.CommandEventArgs"/> instance containing the event data.</param>
    public void DeleteTeam(object sender, CommandEventArgs ce)
    {
        try
        {
            int teamID = Team.SelectedTeam.ID;
            DAOTeam.DeleteTeam(teamID);
            Team.SelectedTeamID = -1;
            RefreshTeamControls();
            this.ShowOperationResult(MessageType.Info,"TeamDeleted");
        }
        catch (Exception e)
        {
            this.ShowOperationResult(MessageType.Error, e.Message);
        }
    }

    /// <summary>
    /// Creates the new team.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void CreateNewTeam(object sender, EventArgs e)
    {
        try
        {
            string teamName = this.NewTeamName.Text;
            int projectID = Team.GetSelectedProjectID();
            Team team = DAOTeam.CreateTeam(teamName, projectID);
            Team.SelectedTeamID = team.ID;
            ShowAddNewTeam(false);
            RefreshTeamControls();
            ShowOperationResult(MessageType.Info,"TeamCreated");
        }
        catch (InconsistentDatabaseException ex)
        {
            ShowOperationResult(MessageType.Error, ex.Message, this.NewTeamName.Text);
        }
    }

    /// <summary>
    /// User wants to hide PanelNewTeam panel
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void CancelCreateNewTeam(object sender, EventArgs e)
    {
        this.ShowAddNewTeam(false);
    }
    #endregion

    #region [TEAM MEMBERS]
    /// <summary>
    /// Loads content of the gridview with users in roles acording to project filter
    /// </summary>
    /// <param name="projectID">The project ID.</param>
    private void LoadUsersInRoles()
    {
        int projectID = Team.SelectedProjectID;
        int teamID = Team.SelectedTeamID;
        IList<UserInRole> users = DAOUserInRole.GetUsersInRole(-1, projectID, teamID);
        this.GridViewRights.DataSource = users;
        this.GridViewRights.DataBind();
    }
    #endregion

    #region [TEAM MEMBER MANAGEMENT]
    

    /// <summary>
    /// User is going to create new team member
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void ShowCreateArea(object sender, EventArgs e)
    {
        DisplayUser(null);
    }

    /// <summary>
    /// Handles the Clicked event of the CancelEditTeamMember control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void CancelEditTeamMember_Clicked(object sender, EventArgs e)
    {
        this.PanelNewTeamMember.Visible = false;
    }

    /// <summary>
    /// User wants to add new team member with specified role
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void AddNewTeamMember_Clicked(object sender, EventArgs e)
    {
        try
        {
            int userID;
            int roleID;
            int teamID;
            LoadUserInRoleIDS(out userID, out roleID, out teamID);
            DAOUserInRole.AddUserInRole(userID, roleID, teamID);
            this.LoadUsersInRoles();
            this.PanelNewTeamMember.Visible = false;
            ShowOperationResult(MessageType.Info,"TeamMemberCreated");
        }
        catch (InconsistentDatabaseException)
        {
            string login = ListBoxUsers.SelectedItem.Text;
            string team = ListBoxTeams.SelectedItem.Text;
            LabelError.Text = String.Format((string)GetLocalResourceObject("DuplicityError"), login, team);
        }
        catch(RequiredUserInputMissing exception)
        {
            ShowOperationResult(MessageType.Error, exception.Message);
        }
    }

    /// <summary>
    /// Loads the user in role IDS.
    /// </summary>
    /// <param name="userID">The user ID.</param>
    /// <param name="roleID">The role ID.</param>
    /// <param name="teamID">The team ID.</param>
    private void LoadUserInRoleIDS(out int userID, out int roleID, out int teamID)
    {
        if (string.IsNullOrEmpty(ListBoxTeams.SelectedValue)) throw new RequiredUserInputMissing("MustSelectTeam");
        if (string.IsNullOrEmpty(ListBoxRoles.SelectedValue)) throw new RequiredUserInputMissing("MustSelectRole");
        if (string.IsNullOrEmpty(ListBoxUsers.SelectedValue)) throw new RequiredUserInputMissing("MustSelectUser");

        userID = Int32.Parse(ListBoxUsers.SelectedValue);
        roleID = Int32.Parse(ListBoxRoles.SelectedValue);
        teamID = Int32.Parse(ListBoxTeams.SelectedValue);
    }

    /// <summary>
    /// Handles the Clicked event of the EditTeamMember control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    public void EditTeamMember_Clicked(object sender, EventArgs e)
    {
        int userID;
        int roleID;
        int teamID;
        LoadUserInRoleIDS(out userID, out roleID, out teamID);
        int userInRoleID = (int)ViewState["EdittingUserInRoleID"];

        try
        {
            DAOUserInRole.EditUserInRole(userInRoleID,userID, roleID, teamID);
        }
        catch (InconsistentDatabaseException exception)
        {
            string login = ListBoxUsers.SelectedItem.Text;
            string team = ListBoxTeams.SelectedItem.Text;
            LabelError.Text = String.Format((string)GetLocalResourceObject("DuplicityError"), login, team);
        }
        
        this.LoadUsersInRoles();
        this.PanelNewTeamMember.Visible = false;
    }

    /// <summary>
    /// Deletes the user in role.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="ce">The <see cref="System.Web.UI.WebControls.CommandEventArgs"/> instance containing the event data.</param>
    public void DeleteUserInRole(object sender, CommandEventArgs ce)
    {
        int userInRoleID = Int32.Parse((string)ce.CommandArgument);
        try
        {
            DAOUserInRole.DeleteUserInRole(userInRoleID);
            this.LoadUsersInRoles();
            ShowOperationResult(MessageType.Info, "TeamMemberDeleted");
        }
        catch (InconsistentDatabaseException e)
        {
            ShowOperationResult(MessageType.Error, e.Message);
        }
        
    }

    /// <summary>
    /// Edits the user in role.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="ce">The <see cref="System.Web.UI.WebControls.CommandEventArgs"/> instance containing the event data.</param>
    public void EditUserInRole(object sender, CommandEventArgs ce)
    {
        int userInRoleID = Int32.Parse((string)ce.CommandArgument);
        ViewState["EdittingUserInRoleID"] = userInRoleID;
        IList<UserInRole> users = DAOUserInRole.GetUsersInRole(userInRoleID, -1, -1);
        UserInRole user = users[0];
        DisplayUser(user);
    }

    /// <summary>
    /// Displays the user in role
    /// </summary>
    /// <param name="user">The user.</param>
    private void DisplayUser(UserInRole user)
    {
        LoadAvaiableTeams();
        LoadAllUsers();
        LoadAllRoles();

        if (user != null)
        {
            ListBoxTeams.Items.FindByValue(user.TeamID.ToString()).Selected = true;
            ListBoxRoles.Items.FindByValue(user.RoleID.ToString()).Selected = true;
            ListBoxUsers.Items.FindByValue(user.UserID.ToString()).Selected = true;
        }
        else 
        { 
        }
        this.PanelNewTeamMember.Visible = true;
        this.ButtonAdd.Visible = user==null;
        this.ButtonEdit.Visible = user!=null;
        //LabelError.Text = "";
    }

    /// <summary>
    /// Loads content of listbox of all roles.
    /// </summary>
    private void LoadAllRoles()
    {
        IList<Role> roles = DAORole.GetAllRoles(true);
        ListBoxRoles.DataTextField = "Name";
        ListBoxRoles.DataValueField = "ID";
        ListBoxRoles.DataSource = roles;
        ListBoxRoles.DataBind();
    }

    /// <summary>
    /// Loads content of listbox of all users.
    /// </summary>
    private void LoadAllUsers()
    {
        IList<User> users = DAOUser.GetTeamMembers();
        ListBoxUsers.DataSource = users;
        ListBoxUsers.DataValueField = "ID";
        ListBoxUsers.DataTextField = "ExtendedUserName";
        ListBoxUsers.DataBind();
    }

    /// <summary>
    /// Loads content of listbox of the avaiable teams.
    /// </summary>
    private void LoadAvaiableTeams()
    {
        int projectID = Team.SelectedProjectID;
        int teamID = Team.SelectedTeamID;
        IList<Team> teams = projectID != null
            ? DAOTeam.GetAllTeams(projectID)
            : new List<Team>();
        ListBoxTeams.DataTextField = "Name";
        ListBoxTeams.DataValueField = "ID";
        ListBoxTeams.DataSource = teams;
        ListBoxTeams.DataBind();
        if ( teamID != -1)
        {
            ListBoxTeams.Items.FindByValue(teamID.ToString()).Selected = true;
        }
    }
    #endregion

    #region [ Settings ]

    /// <summary>
    /// Gets a value indicating whether this instance is editable.
    /// </summary>
    /// <value>
    /// 	<c>true</c> if this instance is editable; otherwise, <c>false</c>.
    /// </value>
    public override bool IsEditable
    {
        get { return false; }
    }

    /// <summary>
    /// Shows the edit.
    /// </summary>
    public override void ShowEdit()
    {
        this.EditPrototypeWidget.Visible = true;
    }

    /// <summary>
    /// Hides the edit.
    /// </summary>
    public override void HideEdit()
    {
        this.EditPrototypeWidget.Visible = false;
    }
    #endregion

    
}
